import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:netease_music/component/DoPlayControl.dart';
import 'package:netease_music/component/TopicUi.dart';
import 'package:netease_music/component/category_nav.dart';
import 'package:netease_music/netService.dart';
import 'package:netease_music/playService.dart';
import 'package:netease_music/view/mainPage.dart';
import 'package:provider/provider.dart';

main() {
  runApp(MultiProvider(
    providers: [
      ChangeNotifierProvider(
        create: (_) => CurrentProvider(),
      ),
      ChangeNotifierProvider(
        create: (_) => TopicUiPlayListProvider(),
      ),
      ChangeNotifierProvider(create: (_) {
        return PlayProvider();
      })
    ],
    child: const MyApp(),
  ));
}

PageRouteBuilder _createPageRoute(Widget page) {
  return PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) => page,
    transitionDuration: const Duration(seconds: 3),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      const begin = Offset(1.0, 0.0); // 从右侧滑入
      const end = Offset.zero; // 到达目标位置
      const curve = Curves.ease; // 动画曲线

      var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
      var offsetAnimation = animation.drive(tween);

      return SlideTransition(
        position: offsetAnimation,
        child: child,
      );
    },
  );
}

final GoRouter _router = GoRouter(
  initialLocation: '/',
  routes: [
    ShellRoute(
      builder: (context, state, child) {
        return MainPage(child: child);
      },
      routes: [
        ShellRoute(
          builder: (c, s, child) {
            return CategoryNavigationBar(child);
          },
          routes: [
            GoRoute(
              path: '/',
              pageBuilder: (c, s) {
                return CustomTransitionPage(
                  child: const TopicUi('/top/playlist'),
                  transitionsBuilder:
                      (c1, animation, secondaryAnimation, child) {
                    return _createPageRoute(child).buildTransitions(
                        c1, animation, secondaryAnimation, child);
                  },
                );
              },
            ),
            GoRoute(
              path: '/1',
              pageBuilder: (c, s) {
                return CustomTransitionPage(
                  child: const TopicUi('/top/playlist/highquality'),
                  transitionsBuilder:
                      (c1, animation, secondaryAnimation, child) {
                    return _createPageRoute(child).buildTransitions(
                        c1, animation, secondaryAnimation, child);
                  },
                );
              },
            ),
            GoRoute(
              path: '/detail',
              pageBuilder: (c, s) {
                int id = s.extra as int;
                return CustomTransitionPage(
                  child: ItemUi(id: id),
                  transitionsBuilder:
                      (c1, animation, secondaryAnimation, child) {
                    return _createPageRoute(child).buildTransitions(
                        c1, animation, secondaryAnimation, child);
                  },
                );
              },
            ),
            GoRoute(
              path: '/todayPlayList',
              pageBuilder: (c, s) {
                // c.read<CurrentProvider>().clearPlayList();
                return CustomTransitionPage(
                  child: const TodayPlayListUi(),
                  transitionsBuilder:
                      (c1, animation, secondaryAnimation, child) {
                    return _createPageRoute(child).buildTransitions(
                        c1, animation, secondaryAnimation, child);
                  },
                );
              },
            ),
          ],
        ),
        GoRoute(
          path: '/yyy',
          builder: (c2, s2) {
            return const LyricPage();
          },
        ),
      ],
    ),
    GoRoute(
      path: '/yyy1',
      builder: (c2, s2) {
        return const LyricPage();
      },
    )
  ],
);

class LyricPage extends StatefulWidget {
  const LyricPage({super.key});

  @override
  State<LyricPage> createState() => _LyricPageState();
}

class _LyricPageState extends State<LyricPage> {
  int _index = 0;
  late Timer timer;
  late List<String> list;
  late ScrollController _controller;

  @override
  void initState() {
    super.initState();
    _controller = ScrollController();
    String l = context.read<CurrentProvider>().currentItem.lyric;
    list = l.split('\n');
    timer = Timer.periodic(const Duration(milliseconds: 100), (s) {
      int duration = context.read<CurrentProvider>().currentItem.duration;
      String lyric = list[_index];
      List<String> t = lyric.split(']');
      var time = t[0].substring(1);
      if (duration >= calc(time) && _index < list.length) {
        _controller.animateTo(_index * 50,
            duration: const Duration(milliseconds: 120), curve: Curves.linear);
        _index++;
      }
    });
  }

  int calc(String s) {
    List<String> parts = s.split(':');
    String minutes = parts[0];
    String seconds = parts[1].replaceAll(RegExp(r'\.\d+'), ''); // 移除小数部分
    int totalSeconds = int.parse(minutes) * 60 + int.parse(seconds);
    return totalSeconds;
  }

  @override
  void dispose() {
    super.dispose();
    timer.cancel();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SizedBox(
          height: 40,
          child: IconButton(
              onPressed: () {
                context.read<PlayProvider>().changePopState();
                context.pop();
              },
              icon: const Icon(
                Icons.keyboard_arrow_down_outlined,
                size: 30,
              )),
        ),
        Expanded(
          child: Row(
            children: [
              Expanded(
                  child: Container(
                margin: const EdgeInsets.symmetric(horizontal: 5),
                clipBehavior: Clip.hardEdge,
                decoration: const BoxDecoration(
                  borderRadius: BorderRadius.all(Radius.circular(20)),
                ),
                child: Image.network(
                    fit: BoxFit.cover,
                    context.read<CurrentProvider>().currentItem.imageUrl),
              )),
              Expanded(
                  child: ListView.builder(
                controller: _controller,
                itemBuilder: (c, i) {
                  return SizedBox(
                    height: 50,
                    child: LayoutBuilder(
                      builder:
                          (BuildContext context, BoxConstraints constraints) {
                        // print(constraints);
                        return Center(
                          child: Padding(
                            padding: const EdgeInsets.symmetric(vertical: 10),
                            child: Text(
                              list[i],
                              style: const TextStyle(fontSize: 22),
                            ),
                          ),
                        );
                      },
                    ),
                  );
                },
                itemCount: list.length,
              ))
            ],
          ),
        ),
      ],
    );
  }
}

enum Mode { recycle, single, random }

class CurrentProvider extends ChangeNotifier {
  final List<String> _naviList = ['最热', '流行', 'Today'];

  List<String> get naviList => _naviList;

  BoxDecoration? get decoration {
    return BoxDecoration(
        image: _currentItem.imageUrl != ''
            ? DecorationImage(
                opacity: 0.4,
                fit: BoxFit.cover,
                image: NetworkImage(_currentItem.imageUrl))
            : null);
  }

  Mode _mode = Mode.recycle;

  Mode get mode => _mode;

  void changeMode(Mode m) {
    _mode = m;
    notifyListeners();
  }

  List<PlayItem> _playItemList = [];

  List<PlayItem> get playItemList => _playItemList;

  int _nextIndex() {
    switch (mode) {
      case Mode.recycle:
        _currentSongIndex = _currentSongIndex + 1;
        return _currentSongIndex;
      case Mode.single:
        return _currentSongIndex;
      case Mode.random:
        return Random().nextInt(_playItemList.length);
    }
  }

  int _prevIndex() {
    switch (mode) {
      case Mode.recycle:
        if (_currentSongIndex == 0) {
          _currentSongIndex = _playItemList.length - 1;
        } else {
          _currentSongIndex = _currentSongIndex - 1;
        }
        return _currentSongIndex;
      case Mode.single:
        return _currentSongIndex;
      case Mode.random:
        return Random().nextInt(_playItemList.length);
    }
  }

  void updatePlayItemList(List<PlayItem> list) {
    _playItemList = list;
    notifyListeners();
  }

  int _currentSongIndex = 0;

  int get currentSongIndex => _currentSongIndex;

  void playPrevious() {
    int index = _prevIndex();
    _doPlay(index);
  }

  Future<void> playNext() async {
    int index = _nextIndex();
    await _doPlay(index);
  }

  Future<void> _doPlay(int index) async {
    PlayItem item = _playItemList[index % _playItemList.length];
    var songdesc = await globalServie.songUrl(item.id);
    item
      ..totalDuration = songdesc.duration
      ..playSourceUrl = songdesc.sourceUrl;
    play(item);
  }

  void updateSongIndex(int index) {
    _currentSongIndex = index;
    notifyListeners();
  }

  IconData _currentIcon = Icons.play_arrow;

  IconData get currentIcon => _currentIcon;

  void updateIcon(IconData data) {
    _currentIcon = data;
    notifyListeners();
  }

  final _currentItem =
      PlayItem(id: -1, name: '', imageUrl: '', duration: 0, index: 0);

  PlayItem get currentItem => _currentItem;

  void updateTotalDuration(int duration) {
    _currentItem.totalDuration = duration;

    notifyListeners();
  }

  void updatePosition(int duration) {
    _currentItem.duration = duration;
    notifyListeners();
  }

  void seekForDuration(Duration d) {
    playService.seek(d);
  }

  Future<void> play(PlayItem item) async {
    _currentItem
      ..totalDuration = item.totalDuration
      ..name = item.name
      ..playSourceUrl = item.playSourceUrl
      ..imageUrl = item.imageUrl;
    _currentIcon = Icons.pause_circle_outline;
    _currentSongIndex = item.index;
    String lyric = await globalServie.lyric(item.id);
    _currentItem.lyric = lyric;
    playService.play(_currentItem.playSourceUrl);
    notifyListeners();
  }
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      theme: ThemeData(
        fontFamily: 'mi',
      ),
      debugShowCheckedModeBanner: false,
      routerConfig: _router,
    );
  }
}

class ItemUi extends StatefulWidget {
  final int id;

  const ItemUi({super.key, required this.id});

  @override
  State<ItemUi> createState() => _ItemUiState();
}

class _ItemUiState extends State<ItemUi> {
  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        IconButton(
            onPressed: () {
              context.pop();
            },
            icon: const Icon(Icons.keyboard_arrow_left_outlined)),
        Expanded(
          child: ListView.builder(
            itemBuilder: (c, i) {
              return PlayListUi(i);
            },
            itemCount: context.watch<CurrentProvider>().playItemList.length,
          ),
        ),
      ],
    );
  }

  @override
  void initState() {
    super.initState();
    _loadResource();
    // context.read<CurrentProvider>().updatePlayItemList(playItemList);
  }

  void _loadResource() async {
    var playDetail = await globalServie.playDetail(widget.id);
    Provider.of<CurrentProvider>(context, listen: false)
        .updatePlayItemList(playDetail);
  }
}

class PlayListUi extends StatefulWidget {
  final int index;

  const PlayListUi(this.index, {super.key});

  @override
  State<PlayListUi> createState() => _PlayListUiState();
}

class _PlayListUiState extends State<PlayListUi> {
  bool isMouseEnter = false;
  bool isClicked = false;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    PlayItem item = context.read<CurrentProvider>().playItemList[widget.index];
    return MouseRegion(
      onEnter: (_) {
        setState(() {
          isMouseEnter = true;
          isClicked = true;
        });
      },
      onExit: (_) {
        setState(() {
          isMouseEnter = false;
          isClicked = false;
        });
      },
      child: GestureDetector(
        onTap: () async {
          var songDesc = await globalServie.songUrl(item.id);
          context.read<CurrentProvider>().play(item
            ..totalDuration = songDesc.duration
            ..playSourceUrl = songDesc.sourceUrl);
        },
        onDoubleTap: () {
          player.pause();
        },
        child: Container(
          margin: const EdgeInsets.symmetric(horizontal: 8),
          height: isClicked ? 80 : 50,
          decoration: BoxDecoration(
            image: isClicked
                ? DecorationImage(
                    opacity: 0.5,
                    fit: BoxFit.cover,
                    image: NetworkImage(
                      "${item.imageUrl}?param=200y200",
                    ))
                : null,
          ),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              AnimatedContainer(
                width: isClicked ? 80 : 40,
                height: isClicked ? 80 : 40,
                decoration: BoxDecoration(
                  image: DecorationImage(
                      image: NetworkImage(item.imageUrl), fit: BoxFit.cover),
                ),
                duration: const Duration(milliseconds: 100),
              ),
              Text(item.name),
            ],
          ),
        ),
      ),
    );
  }
}

class PlayItem {
  int id;
  String name;
  String imageUrl;
  int duration;
  int totalDuration;
  String playSourceUrl;
  int index;
  String lyric;

  PlayItem(
      {required this.id,
      required this.name,
      required this.imageUrl,
      required this.duration,
      this.playSourceUrl = '',
      this.totalDuration = 100,
      required this.index,
      this.lyric = ''});
}

class Category {
  int id;
  String name;

  Category({required this.id, required this.name});
}
